package org.streets.database;

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.List;

/**
 * SQLExcutor is SQL operation's *MAIN* portal
 * 
 * @author dzb
 */
public interface SQLConnection {
	/**
	 * Get a original JDBC Connection Object
	 * @return
	 */
	public Connection connection();
	/**
	 * Begin a transaction in current connection
	 * @return
	 */
	public SQLTransaction beginTransaction();
	/**
	 * Judge current connection is in Transaction or not
	 * @return
	 */
	public boolean isConnectionInTransaction();
	/**
	 * Close current connection
	 */
	public void close();
	/**
	 * Prepare a SQLBatcher for batch execute operation
	 * @param paramSql
	 * @return
	 */
	public SQLBatcher prepare(String paramSql);
	/**
	 * Prepare a SQLBatcher for batch execute operation
	 *  
	 * @param paramSql
	 * @param typeExpr param1_name:type1_alias,param2_name:type2_alias
	 * @return
	 */
	public SQLBatcher prepare(String paramSql, String paramTypeExpr);
	/**
	 * A normal query sql to get a ResultSet object
	 * 
	 * @param paramSql
	 * @param limits
	 * @param params
	 * @return
	 */
	public ResultSet query(String paramSql, Limits limits, Object[] params);
	/**
	 * A normal query sql to get a ResultSet object
	 *  
	 * @param paramSql
	 * @param limits
	 * @param params
	 * @return
	 */
	public ResultSet query(String paramSql, Limits limits, PV... params);
	/**
	 * A sql query to get a Entity object, the entity must has been contributed to @see EntityPackageManager
	 * 
	 * @param <T>
	 * @param paramSql
	 * @param limits
	 * @param clazz
	 * @param params
	 * @return
	 */
	public <T> List<T> query(String paramSql, Class<T> clazz, Limits limits, Object[] params);
	/**
	 * A sql query to get a Entity object, the entity must has been contributed to @see EntityPackageManager 
	 * 
	 * @param <T>
	 * @param paramSql
	 * @param limits
	 * @param clazz
	 * @param params
	 * @return
	 */
	public <T> List<T> query(String paramSql, Class<T> clazz, Limits limits, PV... params);
	/**
	 * A sql query to get a Entity object, the entity transfer from ResultSet by RecordHandler provided 
	 * 
	 * @param <T>
	 * @param paramSql
	 * @param limits
	 * @param handler
	 * @param params
	 * @return
	 */
	public <T> List<T> query(String paramSql, RecordHandler<T> handler, Limits limits, Object[] params);
	/**
	 * A sql query to get a Entity object, the entity transfer from ResultSet by RecordHandler provided
	 *  
	 * @param <T>
	 * @param paramSql
	 * @param limits
	 * @param handler
	 * @param params
	 * @return
	 */
	public <T> List<T> query(String paramSql, RecordHandler<T> handler, Limits limits, PV... params);
	
	/**
	 * 取第一列数据列表，按实际类型返回
	 * @param <T>
	 * @param paramSql
	 * @param limits
	 * @param params
	 * @return
	 */
	public <T> List<T> column(String paramSql, Limits limits, Object[] params);
	/**
	 * 取第一列数据列表，按实际类型返回
	 * @param <T>
	 * @param paramSql
	 * @param limits
	 * @param params
	 * @return
	 */
	public <T> List<T> column(String paramSql, Limits limits, PV... params);
	/**
	 * 取第一列数据列表，按实际类型返回
	 *  
	 * @param <T>
	 * @param paramSql
	 * @param params
	 * @return
	 */
	public <T> T column(String paramSql, Object[] params);
	/**
	 * 取第一列数据列表，按实际类型返回 
	 * @param <T>
	 * @param paramSql
	 * @param params
	 * @return
	 */
	public <T> T column(String paramSql, PV... params);
	
	/**
	 * 批量执行单条或批量SQL语句，如果是多条，语句间以";"分割
	 * @param sqls 单条或批量执行语句(非select)
	 */
	public int[] execute(String sqls);
	/**
	 * Execute a normal sql statement
	 * 
	 * @param paramSql
	 * @param values
	 * @return
	 */
	public int execute(String paramSql, Object[] values);
	/**
	 * Execute a normal sql statement
	 *  
	 * @param paramSql
	 * @param params
	 * @return
	 */
	public int execute(String paramSql, PV... params);
	/**
	 * Execute a Entity by ExecMode provided
	 *  
	 * @param <T>
	 * @param bean
	 * @param create
	 * @return
	 */
	public <T> int execute(T bean, ExecMode mode);
	/**
	 * Execute a batch Entities by ExecMode provided 
	 * 
	 * @param <T>
	 * @param beans
	 * @param create
	 * @return
	 */
	public <T> int[] execute(List<T> beans, ExecMode mode);
	/**
	 * Entity delete method for convenient call
	 * 
	 * @param <T>
	 * @param clazz
	 * @param id
	 * @return
	 */
	public <T> int[] delete(Class<T> clazz, Object... id);
	
//
//	/**
//	 * 
//	 * @param <K>
//	 * @param <V>
//	 * @param paramSql
//	 * @param limits
//	 * @param handler
//	 * @param params
//	 * @return
//	 */
//	public <K, V> Map<K, V> executeQuery(String paramSql,
//			Limits limits, RecordHandler<Map<K, V>> handler, PV... params);
//	/**
//	 * 
//	 * @param <K>
//	 * @param <V>
//	 * @param paramSql
//	 * @param limits
//	 * @param handler
//	 * @param params
//	 * @return
//	 */
//	public <K, V> Map<K, V> executeQuery(String paramSql,
//			Limits limits, RecordHandler<Map<K, V>> handler, Object[] params);
//	/**
//	 * 
//	 * @param <T>
//	 * @param paramSql
//	 * @param limits
//	 * @param handler
//	 * @param params
//	 * @return
//	 */
//	public <T> Collection<T> executeQuery(String paramSql,
//			Limits limits, RecordHandler<Collection<T>> handler, Object[] params);
//	/**
//	 * 
//	 * @param <T>
//	 * @param paramSql
//	 * @param limits
//	 * @param handler
//	 * @param params
//	 * @return
//	 */
//	public <T> Collection<T> executeQuery(String paramSql,	
//			Limits limits, RecordHandler<Collection<T>> handler, PV... params);
		
	/**
	 * 通过ID获取唯一实体
	 * 
	 * @param <T>
	 * @param bean
	 * @param clazz
	 * @return
	 */
	public <T> T unique(Class<T> clazz, Object id);
	/**
	 * 通过SQL和条件参数获取唯一实体 
	 * @param <T>
	 * @param bean
	 * @param clazz
	 * @return
	 */
	public <T> T unique(String paramSql, Class<T> clazz, Object[] params);
	/**
	 * 通过SQL和条件参数获取唯一实体, 实体转换由RecordHandler执行 
	 * 
	 * @param <T>
	 * @param paramSql
	 * @param handler
	 * @param params
	 * @return
	 */
	public <T> T unique(String paramSql, RecordHandler<T> handler, Object[] params);

	/**
	 * 调用某存储过程
	 * 
	 * @param proc
	 * @param params
	 * @return
	 */
	public boolean callProc(String proc, Object[] params);
	/**
	 * 获取SQL语句中某列的数量(DISTINCT)
	 * 
	 * @param sql
	 * @param column
	 * @return
	 */
	public long count(String sql, String column);
    /**
     * 获取SQL数据集的数量
     * 
     * @param sql 
     *      select 语句
     * @return
     */
    public long count(String sql, PV... params);
	/**
	 * 获取带参数SQL语句数据集的数量
	 * @param paramSql
	 * @param params
	 * @return
	 */
	public long count(String paramSql, Object[] params);

}